---
title: 'Recording Events'
description: 'How to record events using spans in your session'
mode: "wide"
---
_View Notebook on <a href={'https://github.com/AgentOps-AI/agentops/blob/main/examples/recording-operations.ipynb'} target={'_blank'}>Github</a>_


{/*  SOURCE_FILE: examples/recording-operations.ipynb  */}

# Recording Operations with Spans
AgentOps v0.4 uses spans to track different types of operations in your agent workflows.

We automatically instrument your LLM Calls from OpenAI, LiteLLM, Cohere, and more. Just make sure their SDKs are imported before initializing AgentOps like we see below.

First let's install the required packages


```python
%pip install -U openai
%pip install -U agentops
%pip install -U python-dotenv
```

Then import them


```python
from openai import OpenAI
import agentops
from agentops.sdk.decorators import session, agent, operation
import os
from dotenv import load_dotenv
```

Next, we'll set our API keys. There are several ways to do this, the code below is just the most foolproof way for the purposes of this notebook. It accounts for both users who use environment variables and those who just want to set the API Key here in this notebook.

[Get an AgentOps API key](https://agentops.ai/settings/projects)

1. Create an environment variable in a .env file or other method. By default, the AgentOps `init()` function will look for an environment variable named `AGENTOPS_API_KEY`. Or...

2. Replace `<your_agentops_key>` below and pass in the optional `api_key` parameter to the AgentOps `init(api_key=...)` function. Remember not to commit your API key to a public repo!


```python
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") or "<your_openai_key>"
AGENTOPS_API_KEY = os.getenv("AGENTOPS_API_KEY") or "<your_agentops_key>"
```


```python
# Initialize the client
agentops.init()

# Optionally, we can add default tags to all sessions
# agentops.init(tags=['Hello Tracker'])

openai_client = OpenAI()

# Create a session to track all operations
@session
def my_session():
    messages = [{"role": "user", "content": "Hello"}]
    response = openai_client.chat.completions.create(
        model="gpt-3.5-turbo", messages=messages, temperature=0.5
    )
    print(response.choices[0].message.content)
    
    # Call our operation
    result = add(2, 4)
    print(f"Addition result: {result}")
    
    # Call our agent
    agent = MyAgent()
    agent.process_data("test data")
    
# Run the session
my_session()
```

Click the AgentOps link above to see your session!

## Operations

AgentOps allows you to record operations using the `@operation` decorator:


```python
from agentops.sdk.decorators import operation

@operation
def add(x, y):
    return x + y
```

## Agents

You can create agent spans that contain operations using the `@agent` decorator:


```python
from agentops.sdk.decorators import agent, operation

@agent
class MyAgent:
    @operation
    def process_data(self, data):
        print(f"Processing data: {data}")
        return f"Processed: {data.upper()}"
```

## Error Handling

Errors are automatically captured by the spans. When an exception occurs within a decorated function, it's recorded in the span:


```python
from agentops.sdk.decorators import operation

@operation
def risky_operation():
    # This exception will be recorded in the span
    try:
        1 / 0  # Ooops! Something went wrong
    except Exception as e:
        print(f"Error occurred: {e}")
        raise

# Create a session that includes the error
@session
def error_session():
    try:
        risky_operation()
    except Exception:
        print("Caught the error, but it's still recorded in the span")

# Run the error session
error_session()
```

## Custom Span Attributes

You can add custom attributes to spans for additional context:


```python
from agentops.sdk.decorators import operation

@operation(name="custom-operation")
def custom_operation(data):
    # Your operation logic here
    return f"Custom: {data}"

# Create a session with custom operation
@session(name="custom-session")
def custom_session():
    result = custom_operation("test")
    print(result)

# Run the custom session
custom_session()
```
